package com.rede.didiok.user.modulelist.rank.restapi;


import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.rede.didiok.common.annotion.log.SysLogHandle;
import com.rede.didiok.common.constant.conf.MessageConf;
import com.rede.didiok.common.constant.conf.RedisConf;
import com.rede.didiok.common.constant.conf.SysConf;
import com.rede.didiok.common.constant.global.Constants;
import com.rede.didiok.common.dto.BehaviorDto;
import com.rede.didiok.common.dto.admin.LinkDto;
import com.rede.didiok.common.dto.rank.RankMemberDto;
import com.rede.didiok.common.dto.user.UserDto;
import com.rede.didiok.common.exception.ThrowableUtils;
import com.rede.didiok.common.exception.exceptionType.FeignException;
import com.rede.didiok.common.feign.AdminFeignClient;
import com.rede.didiok.common.feign.UserFeignClient;
import com.rede.didiok.common.holder.RequestHolder;
import com.rede.didiok.common.utils.*;
import com.rede.didiok.common.validator.group.GetList;
import com.rede.didiok.user.modulelist.rank.entity.MemberTagEntity;
import com.rede.didiok.user.modulelist.rank.entity.RankEntity;
import com.rede.didiok.user.modulelist.rank.entity.RankMemberEntity;
import com.rede.didiok.user.modulelist.rank.manager.RankTaskManager;
import com.rede.didiok.user.modulelist.rank.service.MemberTagService;
import com.rede.didiok.user.modulelist.rank.service.RankCategoryService;
import com.rede.didiok.user.modulelist.rank.service.RankMemberService;
import com.rede.didiok.user.modulelist.rank.service.RankService;

/**
 * 首页 RestApi
 *
 * @author Rede
 * @since 2023-09-04
 */
@RestController
@RequestMapping("/index")
@Api(value = "首页相关接口", tags = {"首页相关接口"})
@Slf4j
public class IndexRestApi {

    @Resource
    private AdminFeignClient adminFeignClient;
    @Resource
    private RankCategoryService rankCategoryService;
    @Resource
    private MemberTagService memberTagService;
    @Resource
    private RankMemberService rankMemberService;
    @Resource
    private RankService rankService;
    @Resource
    private UserFeignClient userFeignClient;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Resource
    private RankTaskManager rankTaskManager;

    @ApiOperation(value = "通过推荐等级获取博客列表", notes = "通过推荐等级获取博客列表")
    @GetMapping("/getRankMemberByLevel")
    public String getBlogByLevel(@ApiParam(name = "level", value = "推荐等级", required = false) @RequestParam(name = "level", required = false, defaultValue = "0") Integer level,
                                 @ApiParam(name = "currentPage", value = "当前页数", required = false) @RequestParam(name = "currentPage", required = false, defaultValue = "1") Long currentPage,
                                 @ApiParam(name = "useSort", value = "使用排序", required = false) @RequestParam(name = "useSort", required = false, defaultValue = "0") Integer useSort) {

        return ResultUtil.result(SysConf.SUCCESS, rankMemberService.getRankMemberPageByLevel(level, currentPage, useSort));
    }

    @ApiOperation(value = "获取首页排行博客", notes = "获取首页排行博客")
    @GetMapping("/getHotRankMember")
    public String getHotRankMember() {

        log.info("获取首页排行博客");
        return ResultUtil.result(SysConf.SUCCESS, rankMemberService.getHotRankMember());
    }

    @ApiOperation(value = "获取最热标签", notes = "获取最热标签")
    @GetMapping("/getHotTag")
    public String getHotTag() {
        String hotTagCount = adminFeignClient.getSysParamsValueByKey(SysConf.HOT_TAG_COUNT);
        // 从Redis中获取最热标签
        String jsonResult = redisUtil.get(RedisConf.RANK_MEMBER_TAG + Constants.SYMBOL_COLON + hotTagCount);
        if (StringUtils.isNotEmpty(jsonResult)) {
            List jsonResult2List = JsonUtils.jsonArrayToArrayList(jsonResult);
            return ResultUtil.result(SysConf.SUCCESS, jsonResult2List);
        }
        List<MemberTagEntity> tagList = memberTagService.getHotTag(Integer.valueOf(hotTagCount));
        if (tagList.size() > 0) {
            redisUtil.setEx(RedisConf.RANK_MEMBER_TAG + Constants.SYMBOL_COLON + hotTagCount, JsonUtils.objectToJson(tagList), 1, TimeUnit.HOURS);
        }
        return ResultUtil.result(SysConf.SUCCESS, tagList);
    }

    @ApiOperation(value = "获取首页最新的博客", notes = "获取首页最新的博客")
    @PostMapping("/getNewRankMember")
    public String getNewRankMember(@Validated({GetList.class}) @RequestBody RankMemberDto rankMemberDto, BindingResult result) {
        ThrowableUtils.checkParamArgument(result);
        log.info("获取首页最新的博客");
        IPage<RankMemberEntity> blogPage = rankMemberService.getNewRankMember(rankMemberDto);
        return ResultUtil.result(SysConf.SUCCESS, blogPage);
    }

    @ApiOperation(value = "mogu-search调用获取博客的接口[包含内容]", notes = "mogu-search调用获取博客的接口")
    @GetMapping("/getRankMemberBySearch")
    public String getRankMemberBySearch(@ApiParam(name = "currentPage", value = "当前页数", required = false) @RequestParam(name = "currentPage", required = false, defaultValue = "1") Long currentPage,
                                  @ApiParam(name = "pageSize", value = "每页显示数目", required = false) @RequestParam(name = "pageSize", required = false, defaultValue = "10") Long pageSize) {

        log.info("获取首页最新的博客");
        return ResultUtil.result(SysConf.SUCCESS, rankMemberService.getRankMemberBySearch(currentPage, null));
    }

    @ApiOperation(value = "按时间戳获取博客", notes = "按时间戳获取博客")
    @GetMapping("/getRankMemberByTime")
    public String getRankMemberByTime(@ApiParam(name = "currentPage", value = "当前页数", required = false) @RequestParam(name = "currentPage", required = false, defaultValue = "1") Long currentPage,
                                @ApiParam(name = "pageSize", value = "每页显示数目", required = false) @RequestParam(name = "pageSize", required = false, defaultValue = "10") Long pageSize) {

        String blogNewCount = adminFeignClient.getSysParamsValueByKey(SysConf.RANK_MEMBER_NEW_COUNT);
        return ResultUtil.result(SysConf.SUCCESS, rankMemberService.getRankMemberByTime(currentPage, Long.valueOf(blogNewCount)));
    }

    @ApiOperation(value = "获取最热榜单", notes = "获取最热榜单")
    @GetMapping("/getHotRank")
    public String getHotRank() {
        String hotRankCount = adminFeignClient.getSysParamsValueByKey(SysConf.HOT_RANK_COUNT);
        // 从Redis中获取最热分类
        String jsonResult = redisUtil.get(RedisConf.RANK + Constants.SYMBOL_COLON + hotRankCount);
        if (StringUtils.isNotEmpty(jsonResult)) {
            List jsonResult2List = JsonUtils.jsonArrayToArrayList(jsonResult);
            return ResultUtil.result(SysConf.SUCCESS, jsonResult2List);
        }
        List<RankEntity> blogSortList = rankService.getHotRank(Integer.valueOf(hotRankCount));
        if (blogSortList.size() > 0) {
            redisUtil.setEx(RedisConf.RANK + Constants.SYMBOL_COLON + hotRankCount, JsonUtils.objectToJson(blogSortList), 1, TimeUnit.HOURS);
        }
        return ResultUtil.result(SysConf.SUCCESS, blogSortList);
    }

    @ApiOperation(value = "获取友情链接", notes = "获取友情链接")
    @GetMapping("/getLink")
    public String getLink() {
        String friendlyLinkCount = adminFeignClient.getSysParamsValueByKey(SysConf.FRIENDLY_LINK_COUNT);
        // 从Redis中获取友情链接
        String jsonResult = redisUtil.get(RedisConf.RANK_MEMBER_LINK + Constants.SYMBOL_COLON + friendlyLinkCount);
        if (StringUtils.isNotEmpty(jsonResult)) {
            List jsonResult2List = JsonUtils.jsonArrayToArrayList(jsonResult);
            return ResultUtil.result(SysConf.SUCCESS, jsonResult2List);
        }
        R linResult = userFeignClient.getLinkListByPageSize(Integer.valueOf(friendlyLinkCount));
        List<LinkDto> linkList;
        if (linResult.getCode() == 0) {
            linkList = linResult.getData(new TypeReference<List<LinkDto>>(){});
        }else {
            throw new FeignException("feign调用异常（通过页大小获取友链列表）：失败");
        }
        if (linkList.size() > 0) {
            redisUtil.setEx(RedisConf.RANK_MEMBER_LINK + Constants.SYMBOL_COLON + friendlyLinkCount, JsonUtils.objectToJson(linkList), 1, TimeUnit.HOURS);
        }
        return ResultUtil.result(SysConf.SUCCESS, linkList);
    }
//    这个接口在admin服务中有
//    @ApiOperation(value = "获取网站配置", notes = "获取友情链接")
//    @GetMapping("/getWebConfig")
//    public String getWebConfig() {
//        log.info("获取网站配置");
//        return ResultUtil.result(SysConf.SUCCESS, webConfigService.getWebConfigByShowList());
//    }

//    这个接口在admin服务中有
//    @ApiOperation(value = "获取网站导航栏", notes = "获取网站导航栏")
//    @GetMapping("/getWebNavbar")
//    public String getWebNavbar() {
//        log.info("获取网站导航栏");
//        return ResultUtil.result(SysConf.SUCCESS, webNavbarService.getAllList());
//    }

//    这个接口的具体实现是在注解 @BussinessLog中的 SysLogHandle 中的
//    @BussinessLog(value = "记录访问页面", behavior = BehaviorEnum.VISIT_PAGE)
//    @ApiOperation(value = "记录访问页面", notes = "记录访问页面")
//    @GetMapping("/recorderVisitPage")
//    public String recorderVisitPage(@ApiParam(name = "pageName", value = "页面名称", required = false) @RequestParam(name = "pageName", required = false) String pageName) {
//
//        if (StringUtils.isEmpty(pageName)) {
//            return ResultUtil.result(SysConf.SUCCESS, MessageConf.PARAM_INCORRECT);
//        }
//        return ResultUtil.result(SysConf.SUCCESS, MessageConf.INSERT_SUCCESS);
//    }

    @ApiOperation(value = "用户行为上报", notes = "用户行为上报")
    @PostMapping("/recorderBehavior")
    public String recorderBehavior(HttpServletRequest request, @RequestBody BehaviorDto behaviorDto) {
        String userUid = RequestHolder.getUserUid();
        Map<String, String> map = IpUtils.getOsAndBrowserInfo(request);
        String os = map.get(SysConf.OS);
        String browser = map.get(SysConf.BROWSER);
        String ip = IpUtils.getIpAddr(request);
        String bizType = "";
        if (behaviorDto.getBizType() != null) {
            bizType = behaviorDto.getBizType().getType();
        }
        // 异步存储日志
        threadPoolTaskExecutor.execute(
                new SysLogHandle(userUid, ip, os, browser,
                        behaviorDto.getBehavior().getBehavior(),
                        behaviorDto.getBizUid(),
                        behaviorDto.getOtherData(), redisUtil, bizType));

        return ResultUtil.result(SysConf.SUCCESS, MessageConf.INSERT_SUCCESS);
    }


    @ApiOperation(value = "获取首页积分排行榜", notes = "获取首页积分排行榜")
    @PostMapping("/getUserTopN")
    public String getUserTopN(@Validated({GetList.class}) @RequestBody UserDto userDto, BindingResult result) {
        ThrowableUtils.checkParamArgument(result);
        log.info("获取首页积分排行榜");
        return userFeignClient.getUserTopN(userDto);
    }


    /**
     * 更新博客信息【点赞、点踩、评论、收藏数】
     * @return
     */
    @PostMapping("/updateRankMemberInfoAll")
    String updateRankMemberInfoAll() {
        rankTaskManager.refreshCommentCountTask(true);
        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

}

